package br.com.hs.nfe.common.validation;

import br.com.hs.nfe.common.enumeration.UFEnum;
import br.com.hs.nfe.common.util.HSConstants;
import br.com.hs.nfe.common.util.StringHelper;

/**
 * Classe de validação de documentos.
 * @author Ranlive Hrysyk
 */
public class ValidadorDocumento {

    private static String FORMAT_CPF = "[0-9]{11}";
    private static String FORMAT_CNPJ = "[0-9]{14}";
    private static String FORMAT_IE_AC = "01[0-9]{11}";
    private static String FORMAT_IE_AL_RR = "24[0-9]{7}";
    private static String FORMAT_IE_AP = "03[0-9]{7}";
    private static String FORMAT_IE_AM_CE_ES_PB_PI_SC = "[0-9]{9}";
    private static String FORMAT_IE_BA = "[0-9]{8,9}";
    private static String FORMAT_IE_DF = "07[0-9]{11}";
    private static String FORMAT_IE_GO = "(10|11|15)[0-9]{7}";
    private static String FORMAT_IE_MA = "12[0-9]{7}";
    private static String FORMAT_IE_MT = "[0-9]{11}";
    private static String FORMAT_IE_MS = "28[0-9]{7}";
    private static String FORMAT_IE_MG = "[0-9]{13}";
    private static String FORMAT_IE_PA = "15[0-9]{7}";
    private static String FORMAT_IE_PR = "[0-9]{10}";
    private static String FORMAT_IE_PE_RO = "[0-9]{9}|[0-9]{14}";
    private static String FORMAT_IE_RJ = "[0-9]{8}";
    private static String FORMAT_IE_RN = "20[0-9]{7,8}";
    private static String FORMAT_IE_RS = "[0-9]{10}";
    private static String FORMAT_IE_SP = "[0-9]{12}|P[0-9]{12}";
    private static String FORMAT_IE_SE = "[0-9]{9}";
    private static String FORMAT_IE_TO = "[0-9]{2}(01|02|03|99)[0-9]{7}";

    /**
     * Valida o CPF/CNPJ
     * @param document Número do documento sem pontuação.
     */
    public static boolean validateDocument(String document) {
        if (!StringHelper.isBlankOrNull(document)) {
            document = StringHelper.unformatDocument(document);
            if (((document.matches(FORMAT_CNPJ)) || (document.matches(FORMAT_CPF))) && (!StringHelper.isRepeated(document))) {
                boolean isCNPJ = document.length() == 14;
                int[] foundDV = {0, 0};
                int dv1 = Integer.parseInt(String.valueOf(document.charAt(document.length() - 2)));
                int dv2 = Integer.parseInt(String.valueOf(document.charAt(document.length() - 1)));
                for (int j = 0; j < 2; j++) {
                    int sum = 0;
                    int coeficient = 2;
                    for (int i = document.length() - 3 + j; i >= 0; i--) {
                        int digit = Integer.parseInt(String.valueOf(document.charAt(i)));
                        sum += digit * coeficient;
                        coeficient++;
                        if ((coeficient <= 9) || (!isCNPJ)) {
                            continue;
                        }
                        coeficient = 2;
                    }
                    foundDV[j] = (11 - sum % 11);
                    if (foundDV[j] < 10) {
                        continue;
                    }
                    foundDV[j] = 0;
                }
                return (dv1 == foundDV[0]) && (dv2 == foundDV[1]);
            }
        }
        return false;
    }

    /**
     * Valida a inscrição estadual por estado.
     * @param ie Número da inscrição estadual sem pontuação.
     * @param uf Estado para validação.
     */
    public static boolean validateIE(String ie, UFEnum uf) {
        if ((!StringHelper.isBlankOrNull(ie)) && (!StringHelper.isRepeated(ie))) {
            if (ie.equalsIgnoreCase(HSConstants.ISENTO)) {
                return true;
            } else {
                ie = StringHelper.unformatDocument(ie);
                //Percorre as UF
                switch (uf.ordinal()) {
                    case 0: //AC
                        return validarIEAC(ie);
                    case 1: //AL
                        return validarIEAL(ie);
                    case 2: //AP
                        return validarIEAP(ie);
                    case 3: //AM
                        return validarIEAM(ie);
                    case 4: //BA
                        return validarIEBA(ie);
                    case 5: //CE
                    case 14: //PB
                    case 17: //PI
                        return validarIECEPBPI(ie);
                    case 6: //DF                    
                        return validarIEDF(ie);
                    case 7: //ES
                    case 23: //SC
                        return validarIEESSC(ie);
                    case 8: //GO
                        return validarIEGO(ie);
                    case 9: //MA
                        return validarIEMA(ie);
                    case 10: //MT
                        return validarIEMT(ie);
                    case 11: //MS
                        return validarIEMS(ie);
                    case 12: //MG
                        return validarIEMG(ie);
                    case 13: //PA
                        return validarIEPA(ie);
                    case 15: //PR
                        return validarIEPR(ie);
                    case 16: //PE
                        return validarIEPE(ie);
                    case 18: //RJ
                        return validarIERJ(ie);
                    case 19: //RN
                        return validarIERN(ie);
                    case 20: //RS
                        return validarIERS(ie);
                    case 21: //RO
                        return validarIERO(ie);
                    case 22: //RR
                        return validarIERR(ie);
                    case 24: //SP
                        return validarIESP(ie);
                    case 25: //SE
                        return validarIESE(ie);
                    case 26: //TO
                        return validarIETO(ie);
                }
            }
        }
        return false;
    }

    /**
     * Soma o calculo do módulo.
     */
    private static int calculateMod(String ie, int[] coeficient, int qtdDV) {
        int sum = 0;
        for (int i = 0; i < ie.length() - qtdDV; i++) {
            int digit = Integer.parseInt(String.valueOf(ie.charAt(i)));
            sum += digit * coeficient[i];
        }
        return sum;
    }

    /**
     * Validar IE do Acre
     */
    private static boolean validarIEAC(String ie) {
        if (ie.matches(FORMAT_IE_AC)) {
            int[] foundDV = {0, 0};
            int dv1 = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 2)));
            int dv2 = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2};
            int[] coeficient2 = {5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2};
            for (int j = 0; j < 2; j++) {
                int sum = 0;
                for (int i = (j == 0 ? 1 : 0); i < ie.length() - 2 + j; i++) {
                    int digit = Integer.parseInt(String.valueOf(ie.charAt(i)));
                    sum += digit * (j == 0 ? coeficient[i] : coeficient2[i]);
                }
                foundDV[j] = (11 - sum % 11);
                if ((foundDV[j] == 10) || (foundDV[j] == 11)) {
                    foundDV[j] = 0;
                }
            }
            return (dv1 == foundDV[0]) && (dv2 == foundDV[1]);
        }
        return false;
    }

    /**
     * Validar IE do Alagoas
     */
    private static boolean validarIEAL(String ie) {
        if (ie.matches(FORMAT_IE_AL_RR)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {9, 8, 7, 6, 5, 4, 3, 2};
            int sum = calculateMod(ie, coeficient, 1);
            int produto = sum * 10;
            int foundDV = produto - ((produto / 11) * 11);
            if (foundDV == 10) {
                foundDV = 0;
            }
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Validar IE do Amapá
     */
    private static boolean validarIEAP(String ie) {
        if (ie.matches(FORMAT_IE_AP)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            long num = Long.parseLong(ie.substring(0, ie.length() - 1));
            int d = 0;
            int p = 0;
            if ((num >= 3000001L) && (num <= 3017000L)) {
                p = 5;
            } else if ((num >= 3017001L) && (num <= 3019022L)) {
                p = 9;
                d = 1;
            }
            int[] coeficient = {9, 8, 7, 6, 5, 4, 3, 2};
            int sum = p + calculateMod(ie, coeficient, 1);
            int foundDV = (11 - sum % 11);
            if (foundDV == 10) {
                foundDV = 0;
            } else if (foundDV == 11) {
                foundDV = d;
            }
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Validar IE do Amazonas
     */
    private static boolean validarIEAM(String ie) {
        if (ie.matches(FORMAT_IE_AM_CE_ES_PB_PI_SC)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {9, 8, 7, 6, 5, 4, 3, 2};
            int sum = calculateMod(ie, coeficient, 1);
            int mod = sum % 11;
            int foundDV = 0;
            if (sum < 11) {
                foundDV = 11 - sum;
            } else {
                if (mod <= 1) {
                    foundDV = 0;
                } else {
                    foundDV = 11 - mod;
                }
            }
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Valida IE da Bahia
     */
    private static boolean validarIEBA(String ie) {
        if (ie.matches(FORMAT_IE_BA)) {
            int dv1 = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 2)));
            int dv2 = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] foundDV = {0, 0};
            int[] coeficient = {7, 6, 5, 4, 3, 2};
            int[] coeficient2 = {8, 7, 6, 5, 4, 3, 2};
            int[] coeficient3 = {9, 8, 7, 6, 5, 4, 3, 2};
            int sum = 0;
            int mod = 0;
            int lenght = ie.length();
            int first = Integer.parseInt(String.valueOf(ie.charAt(0)));
            int type = 0; //tipo 0 (0, 1, 2, 3, 4, 5, 8) ou 1 (6, 7, 9)
            if (first == 6 || first == 7 || first == 9) {
                type = 1;
            }
            int modType = type == 0 ? 10 : 11;
            //Calcula o segundo dígito                    
            sum = calculateMod(ie, lenght == 8 ? coeficient : coeficient2, 2);
            mod = sum % modType;
            if (mod == 0 || (mod == 1 && type == 1)) {
                foundDV[1] = 0;
            } else {
                foundDV[1] = modType - mod;
            }
            //Calcula o primeito dígito
            ie = ie.substring(0, ie.length() - 2) + foundDV[1];
            sum = calculateMod(ie, lenght == 8 ? coeficient2 : coeficient3, 0);
            mod = (sum % modType);
            foundDV[0] = lenght == 8 ? (modType - mod) : mod;
            return (dv1 == foundDV[0]) && (dv2 == foundDV[1]);
        }
        return false;
    }

    /**
     * Validar IE do Ceará/Paraíba/Piauí
     */
    private static boolean validarIECEPBPI(String ie) {
        if (ie.matches(FORMAT_IE_AM_CE_ES_PB_PI_SC)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {9, 8, 7, 6, 5, 4, 3, 2};
            int sum = calculateMod(ie, coeficient, 1);
            int foundDV = 11 - sum % 11;
            if (foundDV == 10 || foundDV == 11) {
                foundDV = 0;
            }
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Validar IE do Distrito Federal
     */
    private static boolean validarIEDF(String ie) {
        if (ie.matches(FORMAT_IE_DF)) {
            int dv1 = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 2)));
            int dv2 = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] foundDV = {0, 0};
            int[] coeficient = {4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2};
            int[] coeficient2 = {5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2};
            for (int j = 0; j < 2; j++) {
                int sum = 0;
                for (int i = (j == 0 ? 1 : 0); i < ie.length() - 2 + j; i++) {
                    int digit = Integer.parseInt(String.valueOf(ie.charAt(i)));
                    sum += digit * (j == 0 ? coeficient[i] : coeficient2[i]);
                }
                foundDV[j] = (11 - sum % 11);
                if ((foundDV[j] == 10) || (foundDV[j] == 11)) {
                    foundDV[j] = 0;
                }
            }
            return (dv1 == foundDV[0]) && (dv2 == foundDV[1]);
        }
        return false;
    }

    /**
     * Validar IE do Espírito Santo/Santa Catarina
     */
    private static boolean validarIEESSC(String ie) {
        if (ie.matches(FORMAT_IE_AM_CE_ES_PB_PI_SC)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {9, 8, 7, 6, 5, 4, 3, 2};
            int sum = calculateMod(ie, coeficient, 1);
            int mod = sum % 11;
            int foundDV = (mod < 2 ? 0 : 11 - mod);
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Validar IE de Goiás
     */
    private static boolean validarIEGO(String ie) {
        if (ie.matches(FORMAT_IE_GO)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {9, 8, 7, 6, 5, 4, 3, 2};
            int sum = calculateMod(ie, coeficient, 1);
            int mod = sum % 11;
            long number = Long.parseLong(ie.substring(0, ie.length() - 1));
            int foundDV = 0;
            if (((number >= 110944020L) && (number < 110944030L)) || (mod == 0)) {
                foundDV = 0;
            } else if (mod == 1) {
                if ((number >= 101031050L) && (number <= 101199979L)) {
                    foundDV = 1;
                } else {
                    foundDV = 0;
                }
            } else {
                foundDV = 11 - mod;
            }
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Validar IE do Maranhão
     */
    private static boolean validarIEMA(String ie) {
        if (ie.matches(FORMAT_IE_MA)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {9, 8, 7, 6, 5, 4, 3, 2};
            int sum = calculateMod(ie, coeficient, 1);
            int mod = sum % 11;
            int foundDV = 0;
            if (mod != 0 && mod != 1) {
                foundDV = 11 - mod;
            }
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Validar IE do Mato Grosso
     */
    private static boolean validarIEMT(String ie) {
        if (ie.length() < 11) {
            ie = StringHelper.completarComZerosAEsquerda(ie, 11);
        }
        if (ie.matches(FORMAT_IE_MT)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {3, 2, 9, 8, 7, 6, 5, 4, 3, 2};
            int sum = calculateMod(ie, coeficient, 1);
            int mod = sum % 11;
            int foundDV = 0;
            if (mod != 0 && mod != 1) {
                foundDV = 11 - mod;
            }
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Validar IE do Mato Grosso do Sul
     */
    private static boolean validarIEMS(String ie) {
        if (ie.matches(FORMAT_IE_MS)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {9, 8, 7, 6, 5, 4, 3, 2};
            int sum = calculateMod(ie, coeficient, 1);
            int mod = sum % 11;
            int foundDV = 0;
            if (mod > 0) {
                foundDV = 11 - mod;
                if (foundDV > 9) {
                    foundDV = 0;
                }
            }
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Validar IE de Minas Gerais
     */
    private static boolean validarIEMG(String ie) {
        if (ie.matches(FORMAT_IE_MG)) {
            int dv1 = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 2)));
            int dv2 = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] foundDV = {0, 0};
            String ieDV1 = ie.substring(0, 3) + "0" + ie.substring(3, ie.length());
            int[] coeficient = {1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2};
            int[] coeficient2 = {3, 2, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2};
            int sum = 0;
            for (int i = 0; i < ieDV1.length() - 2; i++) {
                int digit = Integer.parseInt(String.valueOf(ieDV1.charAt(i)));
                int calc = digit * coeficient[i];
                String alg = Integer.toString(calc);
                for (int j = 0; j < alg.length(); j++) {
                    sum += Integer.parseInt(String.valueOf(alg.charAt(j)));
                }
            }
            foundDV[0] = (Integer.parseInt(String.valueOf(String.valueOf(sum).charAt(0)) + 0) + 10) - sum;
            ie = ie.substring(0, ie.length() - 2) + foundDV[0];
            sum = calculateMod(ie, coeficient2, 0);
            foundDV[1] = sum % 11;
            if (foundDV[1] != 0 || foundDV[1] != 1) {
                foundDV[1] = 11 - foundDV[1];
            }
            return (dv1 == foundDV[0]) && (dv2 == foundDV[1]);
        }
        return false;
    }

    /**
     * Validar IE do Pará
     */
    private static boolean validarIEPA(String ie) {
        if (ie.matches(FORMAT_IE_PA)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {9, 8, 7, 6, 5, 4, 3, 2};
            int sum = calculateMod(ie, coeficient, 1);
            int mod = sum % 11;
            int foundDV = 0;
            if (mod != 0 || mod != 1) {
                foundDV = 11 - mod;
            }
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Validar IE do Paraná
     */
    private static boolean validarIEPR(String ie) {
        if (ie.matches(FORMAT_IE_PR)) {
            int[] foundDV = {0, 0};
            int dv1 = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 2)));
            int dv2 = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {3, 2, 7, 6, 5, 4, 3, 2};
            int[] coeficient2 = {4, 3, 2, 7, 6, 5, 4, 3, 2};
            for (int j = 0; j < 2; j++) {
                int sum = 0;
                for (int i = 0; i < ie.length() - 2 + j; i++) {
                    int digit = Integer.parseInt(String.valueOf(ie.charAt(i)));
                    sum += digit * (j == 0 ? coeficient[i] : coeficient2[i]);
                }
                foundDV[j] = (11 - sum % 11);
                if ((foundDV[j] == 10) || (foundDV[j] == 11)) {
                    foundDV[j] = 0;
                }
            }
            return (dv1 == foundDV[0]) && (dv2 == foundDV[1]);
        }
        return false;
    }

    /**
     * Validar IE do Pernambuco
     */
    private static boolean validarIEPE(String ie) {
        if (ie.matches(FORMAT_IE_PE_RO)) {
            int dv1 = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 2)));
            int dv2 = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] foundDV = {0, 0};
            int[] coeficient = {8, 7, 6, 5, 4, 3, 2};
            int[] coeficient2 = {9, 8, 7, 6, 5, 4, 3, 2};
            int[] coeficient3 = {5, 4, 3, 2, 1, 9, 8, 7, 6, 5, 4, 3, 2};
            int lenght = ie.length();
            for (int j = 0; j < 2; j++) {
                int sum = calculateMod(ie, (lenght == 9 ? (j == 0 ? coeficient : coeficient2) : coeficient3), (lenght == 9 ? 2 - j : 1));
                int mod = sum % 11;
                if (mod != 0 && mod != 1) {
                    foundDV[j] = 11 - mod;
                }
            }
            return lenght == 14 ? (dv2 == foundDV[0]) : (dv1 == foundDV[0]) && (dv2 == foundDV[1]);
        }
        return false;
    }

    /**
     * Validar IE do Rio de Janeiro
     */
    private static boolean validarIERJ(String ie) {
        if (ie.matches(FORMAT_IE_RJ)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {2, 7, 6, 5, 4, 3, 2};
            int sum = calculateMod(ie, coeficient, 1);
            int mod = sum % 11;
            int foundDV = 0;
            if (mod > 1) {
                foundDV = 11 - mod;
            }
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Validar IE do Rio Grande do Norte
     */
    private static boolean validarIERN(String ie) {
        if (ie.matches(FORMAT_IE_RN)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int lenght = ie.length();
            int[] coeficient = {9, 8, 7, 6, 5, 4, 3, 2};
            int[] coeficient2 = {10, 9, 8, 7, 6, 5, 4, 3, 2};
            int sum = calculateMod(ie, lenght == 9 ? coeficient : coeficient2, 1) * 10;
            int foundDV = sum % 11;
            if (foundDV == 10) {
                foundDV = 0;
            }
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Validar IE do Rio Grande do Sul
     */
    private static boolean validarIERS(String ie) {
        if (ie.matches(FORMAT_IE_RS)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {2, 9, 8, 7, 6, 5, 4, 3, 2};
            int sum = calculateMod(ie, coeficient, 1);
            int foundDV = 11 - sum % 11;
            if (foundDV == 10 || foundDV == 11) {
                foundDV = 0;
            }
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Validar IE de Rondônia
     */
    private static boolean validarIERO(String ie) {
        if (ie.matches(FORMAT_IE_PE_RO)) {
            if (ie.length() == 9) {
                ie = StringHelper.completarComZerosAEsquerda(ie.substring(3), 14);
            }
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2};
            int sum = calculateMod(ie, coeficient, 1);
            int foundDV = 11 - sum % 11;
            if (foundDV == 10 || foundDV == 11) {
                foundDV -= 10;
            }
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Validar IE de Roraima
     */
    private static boolean validarIERR(String ie) {
        if (ie.matches(FORMAT_IE_AL_RR)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {1, 2, 3, 4, 5, 6, 7, 8};
            int sum = calculateMod(ie, coeficient, 1);
            int foundDV = sum % 9;
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Validar IE de São Paulo
     */
    private static boolean validarIESP(String ie) {
        if (ie.matches(FORMAT_IE_SP)) {
            int dv1 = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 4)));
            int dv2 = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] foundDV = {0, 0};
            int type = (ie.startsWith("P") ? 1 : 0);
            int[] coeficient = {1, 3, 4, 5, 6, 7, 8, 10};
            int[] coeficient2 = {3, 2, 10, 9, 8, 7, 6, 5, 4, 3, 2};
            String value = type == 1 ? ie.substring(1) : ie;
            for (int j = 0; j < 2; j++) {
                int sum = calculateMod(value, (type == 1 ? coeficient : (j == 0 ? coeficient : coeficient2)), 4 - ((j == 1) && (type == 0) ? 3 : 0));
                int mod = sum % 11;
                foundDV[j] = mod >= 10 ? mod - 10 : mod;
            }
            return type == 1 ? (dv1 == foundDV[0]) : ((dv1 == foundDV[0]) && (dv2 == foundDV[1]));
        }
        return false;
    }

    /**
     * Validar IE de Sergipe
     */
    private static boolean validarIESE(String ie) {
        if (ie.matches(FORMAT_IE_SE)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {9, 8, 7, 6, 5, 4, 3, 2};
            int sum = calculateMod(ie, coeficient, 1);
            int foundDV = 11 - sum % 11;
            if (foundDV == 10 || foundDV == 11) {
                foundDV = 0;
            }
            return dv == foundDV;
        }
        return false;
    }

    /**
     * Validar IE do Tocantins
     */
    private static boolean validarIETO(String ie) {
        if (ie.matches(FORMAT_IE_TO)) {
            int dv = Integer.parseInt(String.valueOf(ie.charAt(ie.length() - 1)));
            int[] coeficient = {9, 8, 7, 6, 5, 4, 3, 2};
            ie = ie.substring(0, 2) + ie.substring(4);
            int sum = calculateMod(ie, coeficient, 1);
            int mod = sum % 11;
            int foundDV = 0;
            if (mod >= 2) {
                foundDV = 11 - mod;
            }
            return dv == foundDV;
        }
        return false;
    }
}
